// Will speed up references to window, and allows munging its name.
var window = this,

// Will speed up references to undefined, and allows munging its name.
undefined,

// Map over iPhoneJS in case of overwrite
_iPhoneJS = window.iPhoneJS,

// Define a local copy of iPhoneJS
iPhoneJS,

// Map over the $p in case of overwrite
_$ = window.$,

// A simple way to check for HTML strings or ID strings
// (both of which we optimize for)
quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,

// Define the main jQuery method
iPhoneJS = window.iPhoneJS = window.$ = function( selector, context ) {
	// The iPhoneJS object is actually just the init constructor 'enhanced'
	return new iPhoneJS.fn.init( selector, context );
};

iPhoneJS.fn = iPhoneJS.prototype = {
	init: function( selector, context ) {
		// Handle $(""), $(null), or $(undefined)
		if ( !selector ) {
			this.length = 0;
			return this;
		}
		
		// Handle $(DOMElement)
		if ( selector.nodeType ) {
			this[0] = selector;
			this.length = 1;
			this.context = selector;
			return this;
		}
		
		// Handle HTML strings
		if ( typeof selector === "string" ) {
			// Are we dealing with HTML string or an ID?
			match = quickExpr.exec( selector );
			
			// Verify a match, and that no context was specified for #id
			if ( match && (match[1] || !context) ) {

				// HANDLE: $("#id")
				if ( !match[1] ) {
					elem = document.getElementById( match[3] );

					// Otherwise, we inject the element directly into the iPhoneJS object
					ret = iPhoneJS( elem || null );
					ret.context = document;
					ret.selector = selector;
					return ret;
				}
			}
			// TODO implementar Sizzle : http://sizzlejs.com 
		}
	}
	
}

// Give the init function the iPhoneJS prototype for later instantiation
iPhoneJS.fn.init.prototype = iPhoneJS.fn;

iPhoneJS.extend = iPhoneJS.fn.extend = function() {
	// copy reference to target object
	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;
		target = arguments[1] || {};
		// skip the boolean and the target
		i = 2;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && !iPhoneJS.isFunction(target) ) {
		target = {};
	}

	// extend jQuery itself if only one argument is passed
	if ( length === i ) {
		target = this;
		--i;
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values
		if ( (options = arguments[ i ]) != null ) {
			// Extend the base object
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				// Prevent never-ending loop
				if ( target === copy ) {
					continue;
				}

				// Recurse if we're merging object values
				if ( deep && copy && typeof copy === "object" && !copy.nodeType ) {
					target[ name ] = iPhoneJS.extend( deep,
						// Never move original objects, clone them
						src || ( copy.length != null ? [ ] : { } ), copy );

				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};

iPhoneJS.extend({
	isFunction: function( obj ) {
		return toString.call(obj) === "[object Function]";
	}
});
